using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Nsb.Classes;
using jQueryApi;

namespace MinionsEdit.Classes
{
    [IgnoreNamespace]
    public class MiProperty : Cluster
    {
        #region Css
        private const string PropertyCss = @"
.MiProperty {
    position: relative;
    display: block;
}
        ";

        public static Dictionary<string,string> DefaultCss = new Dictionary(
            "border-color", "rgba(0,0,0,1)"
        );
        #endregion Css

        protected readonly string PropName;
        protected readonly string Label;
        protected string DefaultValue;
        protected jQueryEvent Event;
        protected jQueryObject Target;
        protected string Units;

        private MiPropPage _page;

        static MiProperty()
        {
            AddStyle(PropertyCss);
        }

        protected MiProperty(string label, string propName)
        {
            Label = label;
            PropName = propName;
            Element = jQuery.FromHtml("<div class='MiProperty'/>");
        }

        #region Properties


        #endregion Properties

        #region Virtual

        [AlternateSignature]
        protected extern virtual string GetLive(string propName);

        protected virtual string GetLive(string propName, string deef)
        {
            string v = deef;
            new Evo()
                .SetValue(propName, null)
                .Evoke(MinionEdit.ActiveFocus.GetCss)
                .Response(delegate(Evo evo) { v = (string)evo.Value ?? v; })
                .Fire();
            return v;
        }


        [AlternateSignature]
        protected virtual extern void SetLive(string propName, Dictionary value);

        protected virtual void SetLive(string propName, string value)
        {
            new Evo()
                .SetValue(propName, value)
                .Evoke(MinionEdit.ActiveFocus.SetCss)
                .Fire();
            QueSave();
        }

        /// <summary>
        /// Gets or sets the widget value.
        /// </summary>
        /// <value>
        /// A string representing the dom value.
        /// </value>
        protected virtual string WidgetValue
        {
            get { throw new Exception("Must be overriden"); }
            // ReSharper disable ValueParameterNotUsed
            set
                // ReSharper restore ValueParameterNotUsed
            {
                // Default set does nothing
            }
        }

        protected virtual string LiveValue
        {
            get
            {
                string tmpValue = "";
                new Evo()
                    .SetValue(PropName, null)
                    .Evoke(MinionEdit.ActiveFocus.GetCss)
                    .Response(delegate(Evo evo) { WidgetValue = tmpValue = (string) evo.Value; })
                    .Fire();
                return tmpValue;
            }
            set
            {
                new Evo()
                    .SetValue(PropName, value)
                    .Evoke(MinionEdit.ActiveFocus.SetCss)
                    .Fire();
                WidgetValue = LiveValue;
                QueSave();
            }
        }

        public virtual MiProperty Initialize(MiPropPage page)
        {
            _page = page;
            Element.AppendTo(_page.Element);
            Units = Units ?? page.Units;
            page.AddProp(Label, this);
            EndBuild();
            return this;
        }

        #endregion Virtual

        #region Chains

        private void EndBuild()
        {
#pragma warning disable 168
            string x = LiveValue; // Value is assigned in Evo response instead of here.
#pragma warning restore 168
        }

        public MiProperty SetDefault(string deef)
        {
            DefaultValue = deef;
            return this;
        }

        public MiProperty SetUnits(string units)
        {
            switch (units)
            {
                case "autoPt":
                    Units = MinionEdit.ActiveFocus.Data.relative ? "%" : "pt";
                    break;
                default:
                    Units = units;
                    break;
            }
            return this;
        }

        #endregion Chains

        #region Events

        protected void ClickEv(jQueryEvent e)
        {
            Event = e;
            Target = jQuery.FromElement(e.Target);
            LiveValue = WidgetValue;
        }

        #endregion Events

        #region Components

        private static int[] _opacityList;

        private static Dictionary<string, string> _alphaValues;

        private static int[] OpacityList
        {
            get
            {
                if (_opacityList == null)
                {
                    _opacityList = new int[101];
                    for (int i = 0; i < 101; i++)
                        _opacityList[i] = i;
                }
                return _opacityList;
            }
        }

        public static Dictionary<string, string> AlphaValues
        {
            get
            {
                if (_alphaValues == null)
                {
                    _alphaValues = new Dictionary();
                    foreach (int i in OpacityList)
                    {
                        _alphaValues[i.ToString()] = (i/100).ToString();
                    }
                }
                return _alphaValues;
            }
        }

        protected static jQueryObject ColorPickerTable(string label)
        {
            string ot = "";
            ot += "<div class='MiColorPicker'>";
            ot += "<div>" + label + " ";
            ot += "<span class='Transparent' title='none'>x</span>";
            ot += "<span class='Transparent' title='transparent'>&#9744;</span>";
            ot += "</div>";
            //ot += (string)Await.Files["ColorPickerTable"];
            ot += MiColorPicker.Html;
            ot += "</div>";
            return jQuery.FromHtml(ot).CSS(new Dictionary("width", 16*7));
        }

        // TODO: Cache dictionaries for efficiency
        public static Dictionary<string,string> DictOf(int st, int en)
        {
            Dictionary<string,string> d = new Dictionary();
            for (int i = st; i <= en; i++)
            {
                d[i.ToString()] = i.ToString();
            }
            return d;
        }

        #endregion Components

        #region Evos

        #endregion Evos

        #region Methods

        public void TriggerUpdate(string label)
        {
            MiProperty prop = _page.GetProp(label);
            if (prop != null)
                prop.Update();
        }

        public void Update()
        {
            WidgetValue = LiveValue;
        }

        protected void QueSave()
        {
            _page.QueSave();
        }

        #endregion Methods
    }
}